package com.shuqi.activity.viewport;

import java.lang.reflect.Method;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Picture;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.GradientDrawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.AbsoluteLayout;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.Scroller;

import com.shuqi.activity.viewport.BookContentView.OnViewEventListener.ClickAction;
import com.shuqi.common.Constant;
import com.shuqi.common.PayTheme;
import com.shuqi.common.utils.Log4an;
import com.shuqi.common.utils.Util;
import com.shuqi.controller.R;
import com.shuqi.model.BookContentSettings;
import com.shuqi.statistics.StatisticsEventID;
import com.shuqi.statistics.StatisticsUtils;

/**
 * 阅读页自定义View
 * 
 * @author linyuren
 * @date 2013-12-19 下午1:37:13
 * @version 1.0
 */
public class BookContentView extends View {

    /** 显示区域宽度 */
    public int mWidth;
    /** 显示区域高度 */
    public int mHeight;
    // 屏幕宽
    public int mScreenWidth;
    // 屏幕高
    public int mScreenHeight;

    /** 为防止Y轴坐标>=View高度，而让其等于View的高度-dI */
    final private float dI = 0.01f;
    /** touch事件down时的x轴坐标 */
    private float mTouchDownX;
    /** touch事件down时的y轴坐标 */
    private float mTouchDownY;
    /** 一次完整touch事件中上一次的x轴坐标 */
    private float mLastTouchX;
    /** 一次完整touch事件中上一次的y轴坐标 */
    private float mLastTouchY;
    /** 设备通知栏高度 */
    private int mNotifactionBarHeight;

    /** Activity对象 */
    private Activity mActivity;

    /** 当前页 */
    private Bitmap mOldContentPageBitmap = null;
    /** 下一页 */
    private Bitmap mNewContentPageBitmap = null;

    /** 是否向右滑动 0空闲状态；1向上拖动；2向下拖动；3向左滑动；4向右滑动；5菜单；6长按事件 */
    private int mScrollDirection = DIRECTION_VOID;

    private float mLastMoveX = 0;

    private volatile int mChangeScrollDirection;
    /** 是否点击阻断touch事件 */
    private boolean flag_blocktouch;
    private volatile boolean mIsRollbackOption;
    /** 空闲状态or点击状态 */
    public static final int DIRECTION_VOID = 0;
    /** 向上拖动 */
    public static final int DIRECTION_TOP = 1;
    /** 向下拖动 */
    public static final int DIRECTION_BOTTOM = 2;
    /** 向左滑动(翻下一页) */
    public static final int DIRECTION_LEFT = 3;
    /** 向右滑动 (翻上一页) */
    public static final int DIRECTION_RIGHT = 4;
    /** 其他 */
    public static final int DIRECTION_OTHER = 5;
    /** 长按事件 */
    public static final int DIRECTION_LONGPRESS = 6;

    /** 边宽度(单位dip) */
    private int mSideWidth = 10;
    /** 事件监听 */
    private OnViewEventListener onViewEventListener;
    private int count = 0;

    // private boolean flag_button=false;
    public int getmWidth() {
        return mWidth;
    }

    public int getmSideWidth() {
        return mSideWidth;
    }

    /** 是否是触摸状态 */
    private boolean mIsTouched;

    /** view是否可用 true可用，false不可用 弹出菜单时候和联网读取下一章时不可用其余可用 */
    private boolean mViewEnabled;

    /** 小说页背面颜色值 */
    private int mReadBackBgColor;

    /** 是否开启点击两侧翻页 */
    private boolean mIsClickSideTurnPage;

    private int[] mCurBitmapShadowColors;

    private GradientDrawable mCurBitmapShadowDrawableRL;

    private boolean mNeedInvalidate = false;

    private static final String TAG = "BookContentView";

    private FlingRunnable mFlingRunnable = new FlingRunnable();

    private int PAGE_RIGHT_BORDER_SHANDOW_WIDTH;

    /** 翻页模式 */
    private int pageTurnMode = 0;
    /** 平滑翻页 */
    public static final int PAGETURN_MODE_SMOOTH = 0;
    /** 仿真翻页 */
    public static final int PAGETURN_MODE_BOOK = 1;
    /** 自由翻页 */
    public static final int PAGETURN_MODE_SCROLL = 2;
    /** 加速度计算工具 */
    private VelocityTracker mVelocityTracker;
    /** 自动动画的控制器 */
    private Scroller mModeScroller;

    /** TODO--------------------关于复制模式的属性----------------- */
    /** 缓存 */
    private Picture defaultPagePicture = new Picture();
    /** 复制功能控件 */
    private PopupWindow copyController;
    /** 复制功能用的临时point */
    private PointF copyPoint;
    /** 点击事件是否可用 */
    private boolean isClickEnabled = true;
    /** 设备density */
    private float density;
    // private long pretime = 0;
    // 是否移动了
    private boolean isMoved;
    // 长按的runnable
    private Runnable mLongPressRunnable;
    // 移动的阈值
    private static final int TOUCH_SLOP = 20;

    // ----------------仿真翻页属性------------------------
    /** 画笔 */
    private Paint paint;
    /** 拖拽点对应的页脚 */
    private int mCornerX;
    private int mCornerY;

    /** 当前页翻起来的部分与下一页显示部分构成的区域path */
    private Path mPath0;
    /** 下一页显示部分构成的区域path */
    private Path mPath1;

    /** 拖拽点 */
    private PointF mTouch = new PointF();
    /** 贝塞尔曲线起始点 */
    private PointF mBezierStart1 = new PointF();
    /** 贝塞尔曲线控制点 */
    private PointF mBezierControl1 = new PointF();
    /** 贝塞尔曲线顶点 */
    private PointF mBeziervertex1 = new PointF();
    /** 贝塞尔曲线结束点 */
    private PointF mBezierEnd1 = new PointF();

    /** 另一条贝塞尔曲线 */
    private PointF mBezierStart2 = new PointF();
    /** 另一条贝塞尔曲线顶点 */
    private PointF mBezierControl2 = new PointF();
    /** 另一条贝塞尔曲线控制点 */
    private PointF mBeziervertex2 = new PointF();
    /** 另一条贝塞尔曲线结束点 */
    private PointF mBezierEnd2 = new PointF();


    /** 拖拽点与页脚的中点 */
    private float mMiddleX;
    private float mMiddleY;
    /** 旋转角度 */
    private float mDegrees;
    /** 拖拽点与页脚的距离 */
    private float mTouchToCornerDis;

    /** 转换颜色的处理类 */
    private ColorMatrixColorFilter mColorMatrixFilter;
    private Matrix mMatrix;
    private float[] mMatrixArray = {0, 0, 0, 0, 0, 0, 0, 0, 1.0f};
    private boolean mIsRTandLB; // 是否属于右上左下
    private float mMaxLength = 0;

    /** 颜色矩阵 */
    private ColorMatrix mColorMatr = null;

    /** 相关阴影 */
    private GradientDrawable mBackShadowDrawableLR;
    private GradientDrawable mBackShadowDrawableRL;
    private GradientDrawable mFolderShadowDrawableLR;
    private GradientDrawable mFolderShadowDrawableRL;

    private GradientDrawable mFrontShadowDrawableHBT;
    private GradientDrawable mFrontShadowDrawableHTB;
    private GradientDrawable mFrontShadowDrawableVLR;
    private GradientDrawable mFrontShadowDrawableVRL;

    // ----------------仿真翻页属性------------------------


    public BookContentView(Context context) {
        this(context, null, 0);
    }

    public BookContentView(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.textViewStyle);
    }

    public BookContentView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mActivity = (Activity) context;


        mLongPressRunnable = new Runnable() {

            @Override
            public void run() {
                if (onViewEventListener != null) {
                    onViewEventListener.onViewLongClick(mTouchDownX, mTouchDownY);
                    onViewEventListener.onViewInLongClickTouching(mTouchDownX, mTouchDownY,
                            mTouchDownX, mTouchDownY, 0, longDownY, longDownX);
                    if (copyPoint == null) {
                        copyPoint = new PointF(mTouchDownX, mTouchDownY);
                    }
                    copyPoint.set(mTouchDownX, mTouchDownY);
                    showOrUpdateMagnifier(copyPoint);
                }
            }
        };

        initData();
    }

    CataLogLayout mCataLogLayout;

    public void setCatalogLayout(CataLogLayout cataLogLayout) {
        this.mCataLogLayout = cataLogLayout;
    }

    /** View大小改变时重新初始化相关数据 */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        initDelayParams();
        if (onViewEventListener != null) {
            onViewEventListener.onViewSizeChanged();
        }
        super.onSizeChanged(w, h, oldw, oldh);
    }

    /**
     * 初始化数据
     */
    private void initData() {
        setDrawingCacheEnabled(true);

        getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                if (mHeight == 0) {
                    initDelayParams();
                }
                return true;
            }
        });

        mTouchSlop = ViewConfiguration.get(mActivity).getScaledTouchSlop();
        Log4an.e("yjd", "mTouchSlop=" + mTouchSlop);
        // 计算书边的宽度
        if (Constant.ISSHOWBOOKSIDE) {
            mSideWidth = (int) (Util.getDensity((Activity) mActivity) * mSideWidth);
        } else {
            mSideWidth = 0;
        }
        // 获取手机的宽度和高度
        mScreenWidth = Util.getScreenWidth();
        mScreenHeight = Util.getScreenHeight();
        // 获取显示的宽度和高度
        mWidth = mScreenWidth - mSideWidth;
        // TODO 任何地方改动后会改变自定义控件高度时 都要重新给mHeight赋值
        mHeight = mScreenHeight;
        // mHeight = getHeight();
        density = Util.getDensity((Activity) mActivity);

        initCurBitmapShadow(Constant.READ_RIGHT_COLORS[PayTheme.getCurrentTheme(mActivity)]);
        PAGE_RIGHT_BORDER_SHANDOW_WIDTH =
                getResources().getDimensionPixelSize(R.dimen.page_animation_slide_shandow_width);
        mVelocityTracker = VelocityTracker.obtain();
        mModeScroller = new Scroller(getContext(), new AccelerateDecelerateInterpolator());// 加速的动画效果

        initSpecEffObjects();
        initSpecEffShadowObjects(PayTheme.getCurrentTheme(mActivity));
        // 构造画笔
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setAntiAlias(true);
        mMaxLength = (float) Math.hypot(mWidth, mHeight);

        /** 设置View不使用硬件加速 */
        try {
            Class<View> c = View.class;
            Method setLayerTypeMethod = c.getDeclaredMethod("setLayerType", int.class, Paint.class);
            if (setLayerTypeMethod != null) {
                int layerType = 1; // View.LAYER_TYPE_SOFTWARE
                setLayerTypeMethod.invoke(this, layerType, null);
            }
        } catch (Exception ignored) {
        }
    }

    private void initCurBitmapShadow(int[] color) {

        mCurBitmapShadowColors = color;
        mCurBitmapShadowDrawableRL =
                new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT,
                        mCurBitmapShadowColors);
        mCurBitmapShadowDrawableRL.setGradientType(GradientDrawable.LINEAR_GRADIENT);
        mCurBitmapShadowDrawableRL.setDither(true);
    }

    public void setCurBitmapShadow(int[] color) {
        initCurBitmapShadow(color);
    }

    /**
     * 设置对应皮肤下仿真翻页的阴影颜色值
     * */
    public void setModeBookShadow(int currentTheme) {
        initSpecEffShadowObjects(currentTheme);
    }

    /** 延迟初始化的数据 */
    public void initDelayParams() {

        initDisolayActionBar();

        initWH();
    }

    private void initWH() {
        mWidth = getWidth() - mSideWidth;
        mHeight = getHeight();
    }

    private void initDisolayActionBar() {
        if (mNotifactionBarHeight == 0) {
            Rect frame = new Rect();
            mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
            mNotifactionBarHeight = frame.top;
        }
    }

    /** 用scroller产生翻页特效 */
    private void startAnimation(int distance) {
        mFlingRunnable.startByScroll(distance);
    }

    private class FlingRunnable implements Runnable {

        private static final int SCROLL_ANIMATION_DURATION = 200;// 500

        private static final int TOUCH_ANIMATION_DURATION = 200;

        private static final int MIN_ANIMATION_DURATION = 200;

        private Scroller mScroller;

        private int mLastFlingX;

        public FlingRunnable() {
            mScroller = new Scroller(getContext(), new DecelerateInterpolator());
        }

        /**
         * 移除消息队列里的上个动作
         */
        private void startCommon() {
            removeCallbacks(this);
        }

        // public void startUsingVelocity(int initialVelocity) {
        // if (initialVelocity == 0)
        // return;
        //
        // startCommon();
        //
        // int initialX = initialVelocity < 0 ? Integer.MAX_VALUE : 0;
        // mLastFlingX = initialX;
        // mScroller.fling(initialX, 0, initialVelocity, 0, 0,
        // Integer.MAX_VALUE, 0, Integer.MAX_VALUE);
        // post(this);
        // }

        /**
         * 另外开启一个线程来横向滑动书页
         * 
         * @param distance 滑动的距离
         */
        public void startByScroll(int distance) {
            startUsingDistance(distance, SCROLL_ANIMATION_DURATION);
        }

        public void startByTouch(int distance) {
            startUsingDistance(distance, TOUCH_ANIMATION_DURATION);
        }

        /**
         * 异步书页偏移的 实际执行方法
         * 
         * @param distance 偏移距离
         * @param during 持续时间
         */
        public void startUsingDistance(int distance, int during) {
            if (distance == 0)
                return;

            startCommon();

            mLastFlingX = 0;
            // 起始点为（0，0），x偏移量为 -distance ，y的偏移量为 0，持续时间
            mScroller.startScroll(0, 0, -distance, 0,
                    Math.max(MIN_ANIMATION_DURATION, Math.abs(distance) * during / mWidth));
            post(this);
        }

        // public void stop(boolean scrollIntoSlots) {
        // removeCallbacks(this);
        // endFling(scrollIntoSlots);
        // }

        /**
         * 停止滑动
         * 
         * @param scrollIntoSlots
         */
        private void endFling(boolean scrollIntoSlots) {
            mScroller.forceFinished(true);
            if (onViewEventListener != null) {
                onViewEventListener.onAnimationFinished();
            }
        }

        // *****************仿真翻页用到的***********************
        /**
         * 开启一个线程来记录仿真翻页动画是否结束
         * */
        public void startAnimationModeBookByTouch() {
            startModeBookUsingDistance();
        }

        public void startModeBookUsingDistance() {
            startCommon();
            post(this);
        }

        // *****************仿真翻页用到的***********************

        @Override
        public void run() {
            if (pageTurnMode == PAGETURN_MODE_SMOOTH) {
                final Scroller scroller = mScroller;
                boolean more = scroller.computeScrollOffset();// 返回true的话 则动画还没有结束
                final int x = scroller.getCurrX();// 返回滚动时 当前的x坐标
                int delta = mLastFlingX - x;
                if (delta != 0) {
                    mLastTouchX += delta;
                    postInvalidate();
                }

                if (more) {
                    mLastFlingX = x;
                    post(this);
                } else {
                    endFling(true);
                    Log.e("mine", "覆盖翻页结束。。。。");
                }
            } else if (pageTurnMode == PAGETURN_MODE_BOOK) {
                final Scroller scroller = mModeScroller;
                boolean more = scroller.computeScrollOffset();// 返回true的话 则动画还没有结束
                if (more) {
                    post(this);
                } else {
                    endFling(true);
                    Log.e("mine", "仿真翻页结束。。。。");
                }
            }
        }

        public boolean isFinished() {
            return mScroller.isFinished();
        }
    }

    /* 判断是否移动,为解决按下就抬起翻页 */
    float mStartX, mStartY;
    boolean mIsRealMove = false;
    int mTouchSlop;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 如果没有设置监听则return
        if (onViewEventListener == null)
            return true;
        // if (isScrollingOnModeScroll) {
        // flag_blocktouch = true;
        // }
        mVelocityTracker.addMovement(event);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                isMoved = false;
                longDownX = event.getX();
                longDownY = event.getY();
                if (!mViewEnabled) {
                    mTouchDownX = event.getX();
                    mTouchDownY = event.getY();
                    return true;
                }

                if (!mFlingRunnable.isFinished()) {
                    return true;
                }

                if (!mModeScroller.isFinished()) {
                    return true;
                }
                abortAnimation();
                mIsTouched = true;
                mChangeScrollDirection = mScrollDirection = DIRECTION_VOID;
                mIsRollbackOption = false;
                mNeedInvalidate = false;

                mTouchDownX = event.getX();
                mTouchDownY = event.getY();

                // curtime = System.currentTimeMillis();
                // TODO 点击可用时再触发长按事件
                if (isClickEnabled) {
                    new LongClickThread(count).start();
                    Log4an.i(TAG, "new LongClickThread(event.getDownTime()).start()");
                    // postDelayed(mLongPressRunnable, ViewConfiguration.getLongPressTimeout());
                }

                mLastTouchX = event.getX();
                mLastTouchY = event.getY();

                mStartX = event.getX();
                mStartY = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                if (!mViewEnabled)
                    return true;

                if (!isMoved) {
                    if (Math.abs(longDownX - event.getX()) > TOUCH_SLOP
                            || Math.abs(longDownY - event.getY()) > TOUCH_SLOP) {
                        // 移动超过阈值，则表示移动了
                        isMoved = true;
                        removeCallbacks(mLongPressRunnable);
                    }
                }

                // 如果是长按时间则return
                if (mScrollDirection == DIRECTION_LONGPRESS) {
                    if (onViewEventListener != null
                            && !(event.getX() == mLastTouchX && event.getY() == mLastTouchY)) {
                        // onViewEventListener.onViewInLongClickTouching(event.getX(), event.getY(),
                        // event.getX(), event.getY(), 0);
                        if (longDownY <= event.getY()) {
                            onViewEventListener.onViewInLongClickTouching(longDownX, longDownY,
                                    event.getX(), event.getY(), 0, longDownY, longDownX);
                        } else {
                            onViewEventListener.onViewInLongClickTouching(event.getX(),
                                    event.getY(), longDownX, longDownY, 0, longDownY, longDownX);
                        }
                        if (copyPoint == null) {
                            copyPoint = new PointF(mTouchDownX, mTouchDownY);
                        }
                        copyPoint.set(event.getX(), event.getY());
                        showOrUpdateMagnifier(copyPoint);
                        mLastTouchX = event.getX();
                        mLastTouchY = event.getY();
                    }
                    return true;
                }
                // 是否是完整的touch事件
                if (!mIsTouched)
                    return true;
                if (!mIsRealMove
                        && (((Math.abs((event.getX() - mStartX))) > mTouchSlop) || ((Math
                                .abs((event.getY() - mStartY))) > mTouchSlop))) {
                    mIsRealMove = true;
                }
                if (mLastTouchX != 0 && mLastTouchY != 0
                        && (mLastTouchX != event.getX() || mLastTouchY != event.getY())) {

                    if (mScrollDirection == DIRECTION_VOID
                            && (Math.abs(event.getX() - mTouchDownX) >= mTouchSlop || Math
                                    .abs(event.getY() - mTouchDownY) >= mTouchSlop)) {
                        if (pageTurnMode == PAGETURN_MODE_SMOOTH || pageTurnMode == PAGETURN_MODE_BOOK) {
                            mChangeScrollDirection =
                                    mScrollDirection =
                                            mLastTouchX < event.getX() ? DIRECTION_RIGHT
                                                    : DIRECTION_LEFT;
                        } else if (pageTurnMode == PAGETURN_MODE_SCROLL) {
                            if (mLastTouchY < event.getY()) {
                                mScrollDirection = DIRECTION_BOTTOM;
                            } else {
                                mScrollDirection = DIRECTION_TOP;
                            }
                        }

                        // 为了防止突然开始滑动的现象出现，需要重置downX、downY
                        mTouchDownX = event.getX();
                        mTouchDownY = event.getY();
                        mLastTouchX = event.getX();
                        mLastTouchY = event.getY();

                        if ((pageTurnMode == PAGETURN_MODE_BOOK || pageTurnMode == PAGETURN_MODE_SMOOTH)
                                && onViewEventListener != null
                                && onViewEventListener.onLoadNextPage(mScrollDirection)) {
                            mIsTouched = false;
                            break;
                        }
                        

                        // 仿真翻页拖动事件处理****************************
                        float t = mTouchDownY;
                        if (mTouchDownY >= mHeight) {
                            t = mHeight - dI;
                        }
                        if (mScrollDirection == DIRECTION_RIGHT
                                || (mScrollDirection == DIRECTION_LEFT
                                        && mTouchDownY > mHeight * 0.38 && mTouchDownY < mHeight * 0.62)) {
                            t = mHeight - dI;
                        }
                        calcCornerXY(t);
                        // 仿真翻页拖动事件处理****************************
                    }

                    if (pageTurnMode == PAGETURN_MODE_SCROLL) {
                        if (onViewEventListener != null) {
                            onViewEventListener.onViewScroll(event.getY() - mLastTouchY);
                        }
                        postInvalidate();
                    }

                    // 仿真翻页拖动事件处理****************************
                    mTouch.x = event.getX();
                    mTouch.y = event.getY();
                    if (mTouch.x >= mWidth) {
                        mTouch.x = mWidth - 1;
                    } else if (mTouch.x <= 0) {
                        mTouch.x = dI;
                    }
                    if (mTouch.y >= mHeight || mTouch.y == mHeight - 1) {
                        mTouch.y = mHeight - dI;
                    } else if (mTouch.y <= 0) {
                        mTouch.y = dI;
                    }
                    if (pageTurnMode == PAGETURN_MODE_BOOK) {
                        if (mScrollDirection == DIRECTION_RIGHT
                                || (mScrollDirection == DIRECTION_LEFT
                                        && mTouchDownY > mHeight * 0.38 && mTouchDownY < mHeight * 0.62)) {
                            if (mScrollDirection == DIRECTION_RIGHT) {
                                mTouch.x -= ((mWidth - event.getX())) / 3;
                                if (mTouch.x >= mWidth) {
                                    mTouch.x = mWidth;
                                }
                            }
                            mTouch.y = mHeight - dI;
                        }
                    }
                    // 仿真翻页拖动事件处理****************************

                    if (mIsRealMove) {
                        postInvalidate();
                    }
                    resetScrollDirection(event.getX());
                }

                mLastTouchX = event.getX();
                mLastTouchY = event.getY();
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                // 释放了
                count++;
                removeCallbacks(mLongPressRunnable);
                mIsRealMove = false;
                if (mCataLogLayout.mLeftSliderLayout.isOpen()) {
                    return true;
                }
                if (!mViewEnabled) {
                    // 为了让view不可用时，也能点出菜单
                    if (Math.abs(event.getX() - mTouchDownX) <= mTouchSlop
                            && Math.abs(event.getY() - mTouchDownY) <= mTouchSlop
                            && onViewEventListener != null
                            && calcTouchArea((int) mTouchDownX, (int) mTouchDownY) == ClickAction.MENU) {
                        mScrollDirection = onViewEventListener.onViewClick(ClickAction.MENU);
                    }
                    return true;
                }

                // 如果是长按事件则return
                if (mScrollDirection == DIRECTION_LONGPRESS) {
                    if (onViewEventListener != null) {
                        // onViewEventListener.onViewInLongClickTouching(longDownX, longDownY,
                        // event.getX(), event.getY(), 0,longDownY);
                        if (longDownY <= event.getY()) {
                            onViewEventListener.onViewInLongClickTouching(longDownX, longDownY,
                                    event.getX(), event.getY(), 0, longDownY, longDownX);
                        } else {
                            onViewEventListener.onViewInLongClickTouching(event.getX(),
                                    event.getY(), longDownX, longDownY, 0, longDownY, longDownX);
                        }
                        closeMagnifier();
                        mLastTouchX = event.getX();
                        mLastTouchY = event.getY();
                    }
                    mScrollDirection = DIRECTION_VOID;
                    return true;
                }

                // 是否是完整的touch事件
                if (!mIsTouched)
                    return true;

                if (pageTurnMode == PAGETURN_MODE_SCROLL) {
                    mVelocityTracker.computeCurrentVelocity(1000);
                    if (onViewEventListener != null) {
                        onViewEventListener.onViewScroll(event.getY() - mLastTouchY);
                    }
                    mLastTouchY = 0;
                    startScollAnimation(0, false);
                }

                mTouch.x = event.getX();
                mTouch.y = event.getY();
                if (mTouch.y >= mHeight) {
                    mTouch.y = mHeight - dI;
                }


                boolean isTouch = mScrollDirection == DIRECTION_VOID;

                // 点击事件
                if (isTouch) {
                    // 计算点击的是哪个区域
                    if (mWidth < mHeight) {// 竖屏时
                        if (this.mIsClickSideTurnPage) { // 开启点击两侧翻页
                            if (calcTouchArea((int) mTouchDownX, (int) mTouchDownY) == ClickAction.MENU) {// 中中
                                mScrollDirection =
                                        onViewEventListener.onViewClick(ClickAction.MENU);
                            } else {
                                mScrollDirection =
                                        onViewEventListener.onViewClick(ClickAction.NEXT_PAGE);
                            }
                        } else {
                            final ClickAction chickAction =
                                    calcTouchArea((int) mTouchDownX, (int) mTouchDownY);

                            mScrollDirection = onViewEventListener.onViewClick(chickAction);

                        }
                    } else {// 横屏时
                        if (this.mIsClickSideTurnPage) { // 开启点击两侧翻页
                            if (calcTouchArea((int) mTouchDownX, (int) mTouchDownY) == ClickAction.MENU) {// 中中
                                mScrollDirection =
                                        onViewEventListener.onViewClick(ClickAction.MENU);
                            } else {
                                mScrollDirection =
                                        onViewEventListener.onViewClick(ClickAction.NEXT_PAGE);
                            }
                        } else {
                            mScrollDirection =
                                    onViewEventListener.onViewClick(calcTouchArea(
                                            (int) mTouchDownX, (int) mTouchDownY));
                        }

                    }

                    // 判断是否是弹出菜单或取消事件
                    if (mScrollDirection == DIRECTION_VOID || mScrollDirection == DIRECTION_OTHER) {
                        mIsTouched = false;
                        break;
                    }

                    mChangeScrollDirection = mScrollDirection;

                    // 重新给mTouch.x和mTouch.y赋值
                    if (pageTurnMode == PAGETURN_MODE_BOOK) {
                        // 计算拖拽点
                        float t = mTouchDownY;
                        if (mTouchDownY >= mHeight) {
                            t = mHeight - dI;
                        }
                        if (mScrollDirection == DIRECTION_RIGHT
                                || (mScrollDirection == DIRECTION_LEFT
                                        && mTouchDownY > mHeight * 0.38 && mTouchDownY < mHeight * 0.62)) {
                            t = mHeight - dI;
                        }
                        calcCornerXY(t);
                        if (mScrollDirection == DIRECTION_RIGHT
                                || (mScrollDirection == DIRECTION_LEFT
                                        && mTouchDownY > mHeight * 0.38 && mTouchDownY < mHeight * 0.62)) {
                            if (mScrollDirection == DIRECTION_RIGHT) {
                                mTouch.x = 0;
                            } else if (mScrollDirection == DIRECTION_LEFT
                                    && mTouchDownY > mHeight * 0.38 && mTouchDownY < mHeight * 0.62) {
                                mTouch.x = mWidth;
                            }
                            mTouch.y = mHeight - dI;
                        }
                    }

                } else {
                    // 重新给mTouch.x和mTouch.y赋值
                    if (pageTurnMode == PAGETURN_MODE_BOOK) {
                        if (mScrollDirection == DIRECTION_RIGHT
                                || (mScrollDirection == DIRECTION_LEFT
                                        && mTouchDownY > mHeight * 0.38 && mTouchDownY < mHeight * 0.62)) {
                            if (mScrollDirection == DIRECTION_RIGHT) {
                                mTouch.x -= ((mWidth - event.getX())) / 3;
                            }
                            mTouch.y = mHeight - dI;
                        }
                    }
                }


                if (pageTurnMode == PAGETURN_MODE_BOOK
                        && (mScrollDirection == DIRECTION_LEFT || mScrollDirection == DIRECTION_RIGHT)) {
                    if (onViewEventListener != null) {
                        onViewEventListener.onViewTouchEnd(mScrollDirection,mChangeScrollDirection != mScrollDirection);
                    }
                    mVelocityTracker.computeCurrentVelocity(1000);

                    recordModeBookStartAnimation();

                    startScollAnimation(-1, mChangeScrollDirection != mScrollDirection);

                    // 重新给mTouch.x和mTouch.y赋值
                    mTouch.x = mCornerX;
                    mTouch.y = mCornerY;
                    if (mTouch.y >= mHeight) {
                        mTouch.y = mHeight - dI;
                    } else if (mTouch.y <= 0) {
                        mTouch.y += dI;
                    }
                }

                if (pageTurnMode == PAGETURN_MODE_SMOOTH
                        && (mScrollDirection == DIRECTION_LEFT || mScrollDirection == DIRECTION_RIGHT)) {
                    if (onViewEventListener != null) {
                        onViewEventListener.onViewTouchEnd(mScrollDirection,
                                mChangeScrollDirection != mScrollDirection);
                    }
                    startScollAnimation(isTouch);
                }


                postInvalidate();
                mIsTouched = false;
                break;
        }
        return true;
    }



    /**
     * 平滑动画
     * 
     * @param isTouch
     */
    private void startScollAnimation(boolean isTouch) {

        int distance = 0;

        if (mChangeScrollDirection != mScrollDirection) {
            mIsRollbackOption = true;
            if (mChangeScrollDirection == DIRECTION_LEFT) {
                distance = (int) -(mLastTouchX - mTouchDownX);
                mScrollDirection = DIRECTION_LEFT;
            } else {
                distance = (int) (mTouchDownX - mLastTouchX);
                mScrollDirection = DIRECTION_RIGHT;
            }
        } else {
            if (mScrollDirection == DIRECTION_LEFT) {
                distance = (int) (mTouchDownX - mLastTouchX) - mWidth;
            } else {
                distance = (int) (mWidth - mLastTouchX + mTouchDownX);
            }
        }

        if (isTouch) {
            mFlingRunnable.startByTouch(distance);
        } else {
            mFlingRunnable.startByScroll(distance);
        }
    }

    /**
     * 记录仿真翻页动画结束线程
     * */
    private void recordModeBookStartAnimation() {
        mFlingRunnable.startAnimationModeBookByTouch();
    }

    private static final int TOUCH_AREA_X_COUNT = 3;
    private static final int TOUCH_AREA_Y_COUNT = 3;

    private ClickAction calcTouchArea(int x, int y) {
        final int x_area_width = mWidth / TOUCH_AREA_X_COUNT;
        final int y_area_height = mHeight / TOUCH_AREA_Y_COUNT;
        switch ((int) (Math.min((x / x_area_width), TOUCH_AREA_X_COUNT - 1) + Math.min(
                (y / y_area_height), TOUCH_AREA_Y_COUNT - 1) * TOUCH_AREA_X_COUNT)) {
            case OnViewEventListener.AREA_TOP_LEFT:
            case OnViewEventListener.AREA_MIDDLE_LEFT:
            case OnViewEventListener.AREA_TOP_MIDDLE:
                return ClickAction.PREV_PAGE;
            case OnViewEventListener.AREA_BOTTOM_LEFT:
            case OnViewEventListener.AREA_TOP_RIGHT:
            case OnViewEventListener.AREA_MIDDLE_RIGHT:
            case OnViewEventListener.AREA_BOTTOM_RIGHT:
            case OnViewEventListener.AREA_BOTTOM_MIDDLE:
                return ClickAction.NEXT_PAGE;

            default:
                return ClickAction.MENU;
        }
    }


    /**
     * 绘制
     * */
    public void onDraw(Canvas canvas) {
        canvas.drawColor(mReadBackBgColor);
        switch (pageTurnMode) {
            case PAGETURN_MODE_SMOOTH:
                switch (mScrollDirection) {
                    case DIRECTION_LEFT:// 翻下一章
                        drawNewContentCanvas(canvas);
                        drawOldContentCanvas(canvas);
                        break;
                    case DIRECTION_RIGHT:// 翻上一章
                        drawOldContentCanvas(canvas);
                        drawNewContentCanvas(canvas);
                        break;
                    case DIRECTION_LONGPRESS:
                        // TODO
                        drawNewContentCanvas(canvas);
                        // drawOldContentCanvas(canvas);
                        // 画复制模式的层
                        Log4an.i(TAG, "画复制模式的层");
                        defaultPagePicture.draw(canvas);
                        break;
                    default:
                        drawOldContentCanvas(canvas);
                        drawNewContentCanvas(canvas);
                        defaultPagePicture.draw(canvas);
                        break;
                }
                break; 
            case PAGETURN_MODE_BOOK:
                switch (mScrollDirection) {
                    case DIRECTION_LEFT:// 翻下一章
                        mCalculatePoints();
                        drawCurrentPageArea(canvas, false);//之前的一页
                        drawNextPageAreaAndShadow(canvas, true);//绘制下一页区域以及阴影部分
                        drawCurrentPageShadow(canvas);//线左边的阴影
                        drawCurrentBackArea(canvas, false);
                        break;
                    case DIRECTION_RIGHT:// 翻上一章
                        mCalculatePoints();
                        drawCurrentPageArea(canvas, true);//绘制当前页区域
                        drawNextPageAreaAndShadow(canvas, false);//绘制下一页区域以及阴影部分
                        drawCurrentPageShadow(canvas);
                        drawCurrentBackArea(canvas, true);
                        break;
                    case DIRECTION_LONGPRESS:
                        drawNewContentCanvas(canvas);
                        // 画复制模式的层
                        defaultPagePicture.draw(canvas);
                        break;
                    default:
                        drawOldContentCanvas(canvas);
                        drawNewContentCanvas(canvas);
                        defaultPagePicture.draw(canvas);
                        break;
                }
                break;
            case PAGETURN_MODE_SCROLL:
                drawScrollContentCanvas(canvas);
                break;
        }

    }

    /**
     * 画上一页正文页翻动时剩下的部分
     * 
     * @param canvas
     */
    private void drawOldContentCanvas(Canvas canvas) {

        if (mOldContentPageBitmap == null) {
            return;
        }

        if (mScrollDirection == DIRECTION_VOID && !mNeedInvalidate) {
            return;
        }

        float moveX = mLastMoveX;
        if (mScrollDirection == DIRECTION_LEFT) {// 向左移动多少就应该绘制偏移多少
            if (mIsRollbackOption) {
                moveX = -mWidth + mLastTouchX - mTouchDownX;
            } else {
                moveX = Math.min(mLastTouchX - mTouchDownX, 0);
            }
        } else {
            moveX = 0;
        }

        canvas.drawBitmap(mOldContentPageBitmap, moveX, 0, null);
        drawShadow(canvas, moveX);

        mLastMoveX = moveX;
    }

    public void drawNewContentCanvas(Canvas canvas) {

        if (mNewContentPageBitmap == null) {
            return;
        }

        float moveX = mLastMoveX;
        if (mScrollDirection == DIRECTION_RIGHT) {// 当前手指触摸的位置的X轴坐标就是要偏移的距离
            if (mIsRollbackOption) {
                moveX = Math.min(mLastTouchX - mTouchDownX, 0);
            } else {
                moveX = -mWidth + mLastTouchX - mTouchDownX;
            }
            drawShadow(canvas, moveX);
        } else {
            moveX = 0;
        }
        canvas.drawBitmap(mNewContentPageBitmap, moveX, 0, null);
    }

    private void drawShadow(Canvas canvas, float moveX) {
        if (Math.round(moveX) >= 0 || Math.floor(moveX) <= -mWidth) {
            return;
        }
        final int rightBorderX = mWidth + (int) moveX - 1;
        mCurBitmapShadowDrawableRL.setBounds(rightBorderX, 0, rightBorderX
                + PAGE_RIGHT_BORDER_SHANDOW_WIDTH, mHeight);
        mCurBitmapShadowDrawableRL.draw(canvas);
    }

    public void postInvalidateRefresh() {
        mScreenWidth = BookContentSettings.getInstance(mActivity).getScreenWidth();
        mScreenHeight = BookContentSettings.getInstance(mActivity).getScreenHeight();
        // 获取显示的宽度和高度
        mWidth = mScreenWidth - mSideWidth;
        // TODO 任何地方改动后会改变自定义控件高度时 都要重新给mHeight赋值
        mHeight = mScreenHeight;

        mNeedInvalidate = true;
        postInvalidate();
    }

    private void resetScrollDirection(float curX) {

        if (curX == mLastTouchX)
            return;

        int tmpScrollDirection = curX > mLastTouchX ? DIRECTION_RIGHT : DIRECTION_LEFT;

        if (mChangeScrollDirection != DIRECTION_VOID
                && mChangeScrollDirection != tmpScrollDirection) {
            mChangeScrollDirection = tmpScrollDirection;
        }
    }

    float downTouchX, downTouchY;

    /** 执行翻上一页操作 */
    public void doTurnPrevPage(boolean isJump) {
        if (!mFlingRunnable.isFinished()) {
            return;
        }

        if (!mModeScroller.isFinished()) {
            return;
        }
        if (onViewEventListener != null) {
            if (onViewEventListener.onLoadNextPage(DIRECTION_RIGHT))
                return;
        }
        if (pageTurnMode != PAGETURN_MODE_BOOK) {
            abortAnimation();
        }
        mScrollDirection = DIRECTION_RIGHT;

        // ****************************************************
        mTouch.x = 0;
        mTouch.y = mHeight - dI;
        mTouchDownX = mTouch.x;
        mTouchDownY = mTouch.y;
        calcCornerXY(mTouch.y);
        if (pageTurnMode == PAGETURN_MODE_BOOK) {
            recordModeBookStartAnimation();
            startScollAnimation(-1, false);
            // 重新给mTouch.x和mTouch.y赋值
            mTouch.x = mCornerX;
            mTouch.y = mCornerY;
            if (mTouch.y >= mHeight) {
                mTouch.y = mHeight - dI;
            } else if (mTouch.y <= 0) {
                mTouch.y += dI;
            }
        }
        // ****************************************************
        if (pageTurnMode == PAGETURN_MODE_SMOOTH) {
            mTouchDownX = 0;
            mLastTouchX = 0;
            mIsRollbackOption = false;
            startAnimation(mWidth);
        }
    }

    /** 执行翻下一页操作 */
    public void doTurnNextPage() {
        if (!mFlingRunnable.isFinished()) {
            return;
        }
        if (!mModeScroller.isFinished()) {
            return;
        }
        if (onViewEventListener != null) {
            if (onViewEventListener.onLoadNextPage(DIRECTION_LEFT))
                return;
        }
        if (pageTurnMode != PAGETURN_MODE_BOOK) {
            abortAnimation();
        }
        mScrollDirection = DIRECTION_LEFT;

        // *****************************
        if (pageTurnMode == PAGETURN_MODE_BOOK) {
            mTouch.x = mWidth * 3 / 4;
            mTouch.y = mHeight * 5 / 8;
        } else {
            mTouch.x = mWidth;
            mTouch.y = mHeight - dI;
        }
        mTouchDownX = mTouch.x;
        mTouchDownY = mTouch.y;
        calcCornerXY(mTouch.y);
        if (pageTurnMode == PAGETURN_MODE_BOOK) {
            recordModeBookStartAnimation();
            startScollAnimation(-1, false);
            // 重新给mTouch.x和mTouch.y赋值
            mTouch.x = mCornerX;
            mTouch.y = mCornerY;
            if (mTouch.y >= mHeight) {
                mTouch.y = mHeight - dI;
            } else if (mTouch.y <= 0) {
                mTouch.y += dI;
            }
        }
        // *************************************
        if (pageTurnMode == PAGETURN_MODE_SMOOTH) {
            mTouchDownX = 0;
            mLastTouchX = 0;
            mIsRollbackOption = false;
            startAnimation(-mWidth);
        }
    }

    /**
     * 设置翻页特效</b><br>
     * 平滑翻页：PAGETURN_MODE_SMOOTH<br>
     * 仿真翻页：PAGETURN_MODE_BOOK<br>
     * 自由翻页：PAGETURN_MODE_SCROLL
     */
    public void setPageTurnMode(int mode) {
        this.pageTurnMode = mode;
    }


    /** 设置点击两侧翻页状态 */
    public void setIsClickSideTurnPage(boolean isClickSide) {
        this.mIsClickSideTurnPage = isClickSide;
    }

    /** 设置View是否可用 true可用，false不可用 */
    public void setViewEnabled(boolean enabled) {
        this.mViewEnabled = enabled;
    }

    /** 获取View是否可用 true可用，false不可用 */
    public boolean getViewEnabled() {
        return this.mViewEnabled;
    }

    /**
     * 当点击menu键时需重置
     * */
    public void onResetmScrollDirection() {
        mScrollDirection = DIRECTION_VOID;
    }

    /**
     * 设置当前页与下一页的显示Bitmap
     * 
     * @param mCurPageBitmap
     * @param mNextPageBitmap
     */
    public void setBitmaps(Bitmap mCurPageBitmap, Bitmap mNextPageBitmap) {
        this.mOldContentPageBitmap = mCurPageBitmap;
        this.mNewContentPageBitmap = mNextPageBitmap;
    }

    /** 设置背景颜色 */
    public void setReadBackBg(int color) {
        mReadBackBgColor = color;
    }

    /** 获取当前背景颜色 */
    public int getReadBackBg() {
        return mReadBackBgColor;
    }

    /** 获取通知栏的高度 */
    public int getBarHeight() {
        return mNotifactionBarHeight;
    }

    /** 设置点击事件监听 */
    public void setOnViewEventListener(OnViewEventListener onViewEventListener) {
        this.onViewEventListener = onViewEventListener;
    }

    /** 事件监听 */
    public interface OnViewEventListener {
        /** 上左区域 */
        public static final int AREA_TOP_LEFT = 0;
        /** 上中区域 */
        public static final int AREA_TOP_MIDDLE = 1;
        /** 上右区域 */
        public static final int AREA_TOP_RIGHT = 2;
        /** 中左区域 */
        public static final int AREA_MIDDLE_LEFT = 3;
        /** 中中区域 */
        public static final int AREA_MIDDLE_MIDDLE = 4;
        /** 中右区域 */
        public static final int AREA_MIDDLE_RIGHT = 5;
        /** 下左区域 */
        public static final int AREA_BOTTOM_LEFT = 6;
        /** 下中区域 */
        public static final int AREA_BOTTOM_MIDDLE = 7;
        /** 下右区域 */
        public static final int AREA_BOTTOM_RIGHT = 8;


        public enum ClickAction {
            MENU, PREV_PAGE, NEXT_PAGE
        }

        /**
         * 请按OnClickListener类的静态属性判断
         * 
         * @param where 区域id
         */
        public int onViewClick(ClickAction action);

        /**
         * touch事件开始 true表示阻断事件
         * 
         * @param scrollDirection 滑动方向
         */
        public boolean onLoadNextPage(int scrollDirection);

        /** ---------------------复制相关的事件----------------- */
        /** TODO 提供长按的坐标 */
        public void onViewLongClick(float x, float y);

        /** 当view在长按事件touch中 */
        public void onViewInLongClickTouching(float startX, float startY, float endX, float endY,
                int handleMode, float longy, float longx);

        /** 当复制模式结束时 */
        public void onViewCopyModeCompleted();

        /** 复制模式的功能按钮事件 */
        public void onViewCopyModeClicked(int which);

        /** ---------------------复制相关的事件----------------- */

        /**
         * touch事件结束
         * 
         * @param scrollDirection 滑动方向
         * @param isBack 是否往回翻
         */
        public void onViewTouchEnd(int scrollDirection, boolean isBack);

        /** 当view大小改变时 */
        public void onViewSizeChanged();


        /** 滑动翻页动画结束 */
        public void onAnimationFinished();

        /** 自由拖动模式，点击滑动时要滑动的距离 */
        public int onViewDistanceInScrollMode();

        /**
         * 拖动
         * 
         * @param dy y轴方向拖动了多少距离
         */
        public void onViewScroll(float dy);
    }

    // **********************************************************仿真翻页处理
    /**
     * 初始化特效相关对象
     */
    private void initSpecEffObjects() {
        // 初始化区域path
        mPath0 = new Path();
        mPath1 = new Path();
        // 构造颜色矩阵并设置颜色数组
        mColorMatr = new ColorMatrix();
        float array[] =
                {0.55f, 0, 0, 0, 80.0f, 0, 0.55f, 0, 0, 80.0f, 0, 0, 0.55f, 0, 80.0f, 0, 0, 0,
                        0.15f, 0};
        mColorMatr.set(array);
        // 构造转换颜色的处理类
        mColorMatrixFilter = new ColorMatrixColorFilter(mColorMatr);

        float array2[] =
                {0.65f, 0, 0, 0, 90.0f, 0, 0.65f, 0, 0, 90.0f, 0, 0, 0.65f, 0, 90.0f, 0, 0, 0,
                        0.25f, 0};
        mColorMatr.set(array2);

        // 构造位置矩阵
        mMatrix = new Matrix();
    }

    /**
     * 初始化特效阴影对象
     */
    private void initSpecEffShadowObjects(int currentTheme) {
        int[] color = null;
        int[] mBackShadowColors = null;
        int[] mFrontShadowColors = null;
        // 夜间或最后一个颜色较深的主题(如果以后增加或减少主题模式此处需要修改)
        if (currentTheme == 7 || currentTheme == 8) {
            color = new int[] {0x1e1e1e, 0xb01e1e1e};// 纵向卷轴阴影颜色数组
            mBackShadowColors = new int[] {0xff242424, 0x242424};// 卷角背面的阴影颜色数组
            mFrontShadowColors = new int[] {0x7a1e1e1e, 0x1e1e1e}; // 卷角前面的阴影颜色数组
        } else {
            color = new int[] {0x6e6e6e, 0xb06e6e6e};// 纵向卷轴阴影颜色数组
            mBackShadowColors = new int[] {0xff6e6e6e, 0x6e6e6e};// 卷角背面的阴影颜色数组
            mFrontShadowColors = new int[] {0x7a6e6e6e, 0x6e6e6e}; // 卷角前面的阴影颜色数组
        }

        // 创建阴影所需的GradientDrawable
        mFolderShadowDrawableRL =
                new GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, color);
        mFolderShadowDrawableRL.setGradientType(GradientDrawable.LINEAR_GRADIENT);
        mFolderShadowDrawableLR =
                new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, color);
        mFolderShadowDrawableLR.setGradientType(GradientDrawable.LINEAR_GRADIENT);


        mBackShadowDrawableRL =
                new GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, mBackShadowColors);
        mBackShadowDrawableRL.setGradientType(GradientDrawable.LINEAR_GRADIENT);
        mBackShadowDrawableLR =
                new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, mBackShadowColors);
        mBackShadowDrawableLR.setGradientType(GradientDrawable.LINEAR_GRADIENT);

        mFrontShadowDrawableVLR =
                new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, mFrontShadowColors);
        mFrontShadowDrawableVLR.setGradientType(GradientDrawable.LINEAR_GRADIENT);
        mFrontShadowDrawableVRL =
                new GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, mFrontShadowColors);
        mFrontShadowDrawableVRL.setGradientType(GradientDrawable.LINEAR_GRADIENT);
        mFrontShadowDrawableHTB =
                new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, mFrontShadowColors);
        mFrontShadowDrawableHTB.setGradientType(GradientDrawable.LINEAR_GRADIENT);
        mFrontShadowDrawableHBT =
                new GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, mFrontShadowColors);
        mFrontShadowDrawableHBT.setGradientType(GradientDrawable.LINEAR_GRADIENT);
    }

    /**
     * 计算拖拽点对应的拖拽脚
     */
    private void calcCornerXY(float y) {
        mCornerX = mWidth;
        if (y <= mHeight / 2f) {
            mCornerY = 0;
            mIsRTandLB = true;
        } else {
            mCornerY = mHeight;
            mIsRTandLB = false;
        }
    }


    /**
     * 求解直线P1P2和直线P3P4的交点坐标
     */
    private PointF getCross(PointF P1, PointF P2, PointF P3, PointF P4) {
        PointF CrossP = new PointF();
        // 二元函数通式： y=ax+b
        float a1 = (P2.y - P1.y) / (P2.x - P1.x);
        float b1 = ((P1.x * P2.y) - (P2.x * P1.y)) / (P1.x - P2.x);
        float a2 = (P4.y - P3.y) / (P4.x - P3.x);
        float b2 = ((P3.x * P4.y) - (P4.x * P3.y)) / (P3.x - P4.x);
        CrossP.x = (b2 - b1) / (a1 - a2);
        CrossP.y = a1 * CrossP.x + b1;
        return CrossP;
    }

    /**
     * 计算贝塞尔曲线各点坐标
     */
    private void mCalculatePoints() {
        // 就算拖拽点与页脚的中点
        mMiddleX = (mTouch.x + mCornerX) / 2;
        mMiddleY = (mTouch.y + mCornerY) / 2;

        // 计算贝塞尔曲线控制点
        mBezierControl1.x =
                mMiddleX - (mCornerY - mMiddleY) * (mCornerY - mMiddleY) / (mCornerX - mMiddleX);
        mBezierControl1.y = mCornerY;
        mBezierControl2.x = mCornerX;
        mBezierControl2.y =
                mMiddleY - (mCornerX - mMiddleX) * (mCornerX - mMiddleX) / (mCornerY - mMiddleY);
        // 计算贝塞尔曲线起点
        mBezierStart1.x = mBezierControl1.x - (mCornerX - mBezierControl1.x) / 2;
        mBezierStart1.y = mCornerY;

        // 当mBezierStart1.x < 0或者mBezierStart1.x > mWidth时
        // 处理如果继续翻页的bug
        if (mTouch.x > 0 && mTouch.x < mWidth) {
            if (mBezierStart1.x < 0 || mBezierStart1.x > mWidth) {
                if (mBezierStart1.x < 0) {
                    mBezierStart1.x = mWidth - mBezierStart1.x;
                }
                float f1 = Math.abs(mCornerX - mTouch.x);
                float f2 = mWidth * f1 / mBezierStart1.x;
                mTouch.x = Math.abs(mCornerX - f2);
                float f3 = Math.abs(mCornerX - mTouch.x) * Math.abs(mCornerY - mTouch.y) / f1;
                mTouch.y = Math.abs(mCornerY - f3);
                mMiddleX = (mTouch.x + mCornerX) / 2;
                mMiddleY = (mTouch.y + mCornerY) / 2;
                mBezierControl1.x =
                        mMiddleX - (mCornerY - mMiddleY) * (mCornerY - mMiddleY)
                                / (mCornerX - mMiddleX);
                mBezierControl1.y = mCornerY;
                mBezierControl2.x = mCornerX;
                mBezierControl2.y =
                        mMiddleY - (mCornerX - mMiddleX) * (mCornerX - mMiddleX)
                                / (mCornerY - mMiddleY);
                mBezierStart1.x = mBezierControl1.x - (mCornerX - mBezierControl1.x) / 2;
            }
        }
        mBezierStart2.x = mCornerX;
        mBezierStart2.y = mBezierControl2.y - (mCornerY - mBezierControl2.y) / 2;

        // 拖拽点与页脚的距离
        mTouchToCornerDis = (float) Math.hypot((mTouch.x - mCornerX), (mTouch.y - mCornerY));

        // 计算贝塞尔曲线结束点
        mBezierEnd1 = getCross(mTouch, mBezierControl1, mBezierStart1, mBezierStart2);
        mBezierEnd2 = getCross(mTouch, mBezierControl2, mBezierStart1, mBezierStart2);

        if (0 == Float.compare(Float.NaN, mBezierEnd1.x))
            mBezierEnd1.x = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mBezierEnd1.y))
            mBezierEnd1.y = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mBezierEnd2.x))
            mBezierEnd2.x = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mBezierEnd2.y))
            mBezierEnd2.y = Float.MAX_VALUE;

        /*
         * mBeziervertex1.x 推导 ((mBezierStart1.x+mBezierEnd1.x)/2+mBezierControl1.x)/2 化简等价于
         * (mBezierStart1.x+ 2*mBezierControl1.x+mBezierEnd1.x) / 4
         * 
         * @计算贝塞尔曲线顶点
         */
        mBeziervertex1.x = (mBezierStart1.x + 2 * mBezierControl1.x + mBezierEnd1.x) / 4;
        mBeziervertex1.y = (2 * mBezierControl1.y + mBezierStart1.y + mBezierEnd1.y) / 4;
        mBeziervertex2.x = (mBezierStart2.x + 2 * mBezierControl2.x + mBezierEnd2.x) / 4;
        mBeziervertex2.y = (2 * mBezierControl2.y + mBezierStart2.y + mBezierEnd2.y) / 4;
        if (0 == Float.compare(Float.NaN, mBeziervertex1.x))
            mBeziervertex1.x = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mBeziervertex1.y))
            mBeziervertex1.y = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mBeziervertex2.x))
            mBeziervertex2.x = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mBeziervertex2.y))
            mBeziervertex2.y = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mMiddleX))
            mMiddleX = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mMiddleY))
            mMiddleY = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mBezierControl1.x))
            mBezierControl1.x = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mBezierControl1.y))
            mBezierControl1.y = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mBezierControl2.x))
            mBezierControl2.x = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mBezierControl2.y))
            mBezierControl2.y = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mBezierStart1.x))
            mBezierStart1.x = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mBezierStart1.y))
            mBezierStart1.y = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mBezierStart2.x))
            mBezierStart2.x = Float.MAX_VALUE;
        if (0 == Float.compare(Float.NaN, mBezierStart2.y))
            mBezierStart2.y = Float.MAX_VALUE;
    }

    /**
     * 绘制当前页区域
     * 
     * @param canvas
     * @param bitmap
     * @param path
     */
    private void drawCurrentPageArea(Canvas canvas, boolean isPrevPage) {
        if (isPrevPage) {
            if (mNewContentPageBitmap == null) {
                return;
            }
        } else {
            if (mOldContentPageBitmap == null) {
                return;
            }
        }

        canvas.save();
        // 构造区域path
        mPath0.reset();
        if (mTouch.y == mHeight - dI) {
            mPath0.moveTo(mTouch.x, 0);
            mPath0.lineTo(mWidth, 0);
            mPath0.lineTo(mWidth, mHeight);
            mPath0.lineTo(mTouch.x, mHeight);
        } else {
            mPath0.moveTo(mBezierStart1.x, mBezierStart1.y);
            mPath0.quadTo(mBezierControl1.x, mBezierControl1.y, mBezierEnd1.x, mBezierEnd1.y);
            mPath0.lineTo(mTouch.x, mTouch.y);
            mPath0.lineTo(mBezierEnd2.x, mBezierEnd2.y);
            mPath0.quadTo(mBezierControl2.x, mBezierControl2.y, mBezierStart2.x, mBezierStart2.y);
            mPath0.lineTo(mCornerX, mCornerY);
        }
        mPath0.close();
        canvas.clipPath(mPath0, Region.Op.XOR);
        if (isPrevPage) {
            canvas.drawBitmap(mNewContentPageBitmap, 0, 0, null);//上一章
        } else {
            canvas.drawBitmap(mOldContentPageBitmap, 0, 0, null);//下一章
        }
        canvas.restore();
    }

    /**
     * 绘制下一页区域以及阴影部分
     * 
     * @param canvas
     * @param bitmap
     */
    private void drawNextPageAreaAndShadow(Canvas canvas, boolean isNextPage) {
        if (isNextPage) {
            if (mNewContentPageBitmap == null) {
                return;
            }
        } else {
            if (mOldContentPageBitmap == null) {
                return;
            }
        }

        // 计算翻页的角度
        mDegrees =
                (float) Math.toDegrees(Math.atan2(mBezierControl1.x - mCornerX, mBezierControl2.y
                        - mCornerY));
        // 计算阴影的大小
        int leftx;
        int rightx;
        GradientDrawable mBackShadowDrawable;
        if (mIsRTandLB) {
            leftx = (int) (mBezierStart1.x);
            rightx = (int) (mBezierStart1.x + mTouchToCornerDis / 4);
            mBackShadowDrawable = mBackShadowDrawableLR;
        } else {
            leftx = (int) (mBezierStart1.x - mTouchToCornerDis / 4);
            rightx = (int) mBezierStart1.x;
            mBackShadowDrawable = mBackShadowDrawableRL;
        }

        // 构造区域path
        mPath1.reset();
        if (mTouch.y == mHeight - dI) {
            rightx = (int) ((mBezierStart1.x + 1) + (mBezierStart1.x + 1 - mTouch.x) / 3);
            mPath1.moveTo(rightx, 0);
            mPath1.lineTo(rightx, mHeight);
            mPath1.lineTo(mWidth, mHeight);
            mPath1.lineTo(mWidth, 0);
        } else {
            mPath1.moveTo(mBezierStart1.x, mBezierStart1.y);
            mPath1.lineTo(mBeziervertex1.x, mBeziervertex1.y);
            mPath1.lineTo(mBeziervertex2.x, mBeziervertex2.y);
            mPath1.lineTo(mBezierStart2.x, mBezierStart2.y);
            mPath1.lineTo(mCornerX, mCornerY);
        }
        mPath1.close();

        // 绘制下一页区域以及阴影部分
        canvas.save();
        canvas.clipPath(mPath0);
        canvas.clipPath(mPath1, Region.Op.INTERSECT);
        if (isNextPage) {
            canvas.drawBitmap(mNewContentPageBitmap, 0, 0, null);
        } else {
            canvas.drawBitmap(mOldContentPageBitmap, 0, 0, null);
        }
        canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y);
        mBackShadowDrawable.setBounds(leftx, (int) mBezierStart1.y, rightx,
                (int) (mMaxLength + mBezierStart1.y));
        mBackShadowDrawable.draw(canvas);
        canvas.restore();
    }


    /**
     * 绘制翻起页的阴影
     * 
     * @param canvas
     */
    private void drawCurrentPageShadow(Canvas canvas) {
        double degree;
        int shadowWidth = 20;
        if (mIsRTandLB) {
            degree =
                    Math.PI
                            / 4
                            - Math.atan2(mBezierControl1.y - mTouch.y, mTouch.x - mBezierControl1.x);
        } else {
            degree =
                    Math.PI
                            / 4
                            - Math.atan2(mTouch.y - mBezierControl1.y, mTouch.x - mBezierControl1.x);
        }
        // 翻起页阴影顶点与touch点的距离
        double d1 = shadowWidth * Math.sqrt(2) * Math.cos(degree);
        double d2 = shadowWidth * Math.sqrt(2) * Math.sin(degree);
        float x = (float) (mTouch.x + d1);
        float y;
        if (mIsRTandLB) {
            y = (float) (mTouch.y + d2);
        } else {
            y = (float) (mTouch.y - d2);
        }
        mPath1.reset();
        mPath1.moveTo(x, y);
        mPath1.lineTo(mTouch.x, mTouch.y);

        /** 防止某些值为Infinite（在4.1中clipPath的path里的值为Infinite时，会报C代码错误），设置成屏幕宽 */
        if (mTouch.y == mHeight - dI) {
            if (Float.isInfinite(mBezierControl1.x)) {
                mBezierControl1.x = mScreenWidth;
            }
            if (Float.isInfinite(mBezierStart1.x)) {
                mBezierStart1.x = mScreenWidth;
            }
        }
        /*******************************************/

        mPath1.lineTo(mBezierControl1.x, mBezierControl1.y);
        mPath1.lineTo(mBezierStart1.x, mBezierStart1.y);
        mPath1.close();
        float rotateDegrees;
        canvas.save();
        canvas.clipPath(mPath0, Region.Op.XOR);
        canvas.clipPath(mPath1, Region.Op.INTERSECT);
        int leftx;
        int rightx;
        GradientDrawable mCurrentPageShadow;
        if (mIsRTandLB) {
            leftx = (int) (mBezierControl1.x);
            rightx = (int) mBezierControl1.x + shadowWidth;
            mCurrentPageShadow = mFrontShadowDrawableVLR;
        } else {
            leftx = (int) (mBezierControl1.x - shadowWidth);
            rightx = (int) mBezierControl1.x + 1;
            mCurrentPageShadow = mFrontShadowDrawableVRL;
        }

        rotateDegrees =
                (float) Math.toDegrees(Math.atan2(mTouch.x - mBezierControl1.x, mBezierControl1.y
                        - mTouch.y));
        canvas.rotate(rotateDegrees, mBezierControl1.x, mBezierControl1.y);
        mCurrentPageShadow.setBounds(leftx, (int) (mBezierControl1.y - mMaxLength), rightx,
                (int) (mBezierControl1.y));
        mCurrentPageShadow.draw(canvas);
        canvas.restore();

        /** 此段代码是增加绘制纵向卷轴的左边侧阴影效果 */
        if (mTouch.y == mHeight - dI) {
            canvas.save();
            float i = (mBezierStart1.x + mBezierControl1.x) / 2;
            float f1 = Math.abs(i - mBezierControl1.x);
            float i1 = (mBezierStart2.y + mBezierControl2.y) / 2;
            float f2 = Math.abs(i1 - mBezierControl2.y);
            float f3 = Math.min(f1, f2);
            canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y);
            GradientDrawable mFolderShadowDrawable;
            int left;
            int right;
            if (mIsRTandLB) {
                left = (int) (mBezierStart1.x - 1);
                right = (int) (mBezierStart1.x + f3 + 1);
                mFolderShadowDrawable = mFolderShadowDrawableLR;
            } else {
                left = (int) (mBezierStart1.x - f3 - 1);
                right = (int) (mBezierStart1.x + 1);
                mFolderShadowDrawable = mFolderShadowDrawableRL;
            }
            canvas.translate(right - mTouch.x + (right - left) - 2, 0);
            mFolderShadowDrawable.setBounds(left, (int) mBezierStart1.y, right,
                    (int) (mBezierStart1.y + mMaxLength));
            mFolderShadowDrawable.draw(canvas);
            canvas.restore();
            return;
        }

        mPath1.reset();
        mPath1.moveTo(x, y);
        mPath1.lineTo(mTouch.x, mTouch.y);
        mPath1.lineTo(mBezierControl2.x, mBezierControl2.y);
        mPath1.lineTo(mBezierStart2.x, mBezierStart2.y);
        mPath1.close();
        canvas.save();
        canvas.clipPath(mPath0, Region.Op.XOR);
        canvas.clipPath(mPath1, Region.Op.INTERSECT);
        if (mIsRTandLB) {
            leftx = (int) (mBezierControl2.y);
            rightx = (int) (mBezierControl2.y + shadowWidth);
            mCurrentPageShadow = mFrontShadowDrawableHTB;
        } else {
            leftx = (int) (mBezierControl2.y - shadowWidth);
            rightx = (int) (mBezierControl2.y + 1);
            mCurrentPageShadow = mFrontShadowDrawableHBT;
        }
        rotateDegrees =
                (float) Math.toDegrees(Math.atan2(mBezierControl2.y - mTouch.y, mBezierControl2.x
                        - mTouch.x));
        canvas.rotate(rotateDegrees, mBezierControl2.x, mBezierControl2.y);
        float temp;
        if (mBezierControl2.y < 0) {
            temp = mBezierControl2.y - mHeight;
        } else {
            temp = mBezierControl2.y;
        }
        int ppp = (int) Math.hypot(mBezierControl2.x, temp);
        if (ppp > mMaxLength) {
            mCurrentPageShadow.setBounds((int) (mBezierControl2.x - shadowWidth) - ppp, leftx,
                    (int) (mBezierControl2.x + mMaxLength) - ppp, rightx);
        } else {
            mCurrentPageShadow.setBounds((int) (mBezierControl2.x - mMaxLength), leftx,
                    (int) (mBezierControl2.x), rightx);
        }
        mCurrentPageShadow.draw(canvas);
        canvas.restore();
    }

    /**
     * 绘制翻起页背面
     * 
     * @param canvas
     * @param bitmap
     */
    private void drawCurrentBackArea(Canvas canvas, boolean isPrevPage) {
        if (isPrevPage) {
            if (mNewContentPageBitmap == null) {
                return;
            }
        } else {
            if (mOldContentPageBitmap == null) {
                return;
            }
        }

        // 计算起点到控制点的中点最短距离
        float i = (mBezierStart1.x + mBezierControl1.x) / 2;
        float f1 = Math.abs(i - mBezierControl1.x);
        float i1 = (mBezierStart2.y + mBezierControl2.y) / 2;
        float f2 = Math.abs(i1 - mBezierControl2.y);
        float f3 = Math.min(f1, f2);

        // 绘制阴影部分
        GradientDrawable mFolderShadowDrawable;
        int left;
        int right;
        if (mIsRTandLB) {
            left = (int) (mBezierStart1.x - 1);
            right = (int) (mBezierStart1.x + f3 + 1);
            mFolderShadowDrawable = mFolderShadowDrawableLR;
        } else {
            left = (int) (mBezierStart1.x - f3 - 1);
            right = (int) (mBezierStart1.x + 1);
            mFolderShadowDrawable = mFolderShadowDrawableRL;
        }

        // 构造翻起页背面区域path
        mPath1.reset();
        if (mTouch.y == mHeight - dI) {
            mPath1.moveTo(mTouch.x, 0);
            mPath1.lineTo(mTouch.x, mHeight);
            right = (int) (mBezierStart1.x + 1 + (mBezierStart1.x + 1 - mTouch.x) / 3);
            mPath1.lineTo(right, mHeight);
            mPath1.lineTo(right, 0);
        } else {
            mPath1.moveTo(mBeziervertex2.x, mBeziervertex2.y);
            mPath1.lineTo(mBeziervertex1.x, mBeziervertex1.y);
            mPath1.lineTo(mBezierEnd1.x, mBezierEnd1.y);
            mPath1.lineTo(mTouch.x, mTouch.y);
            mPath1.lineTo(mBezierEnd2.x, mBezierEnd2.y);
        }
        mPath1.close();
        canvas.save();
        canvas.clipPath(mPath0);
        canvas.clipPath(mPath1, Region.Op.INTERSECT);

        float dis = (float) Math.hypot(mCornerX - mBezierControl1.x, mBezierControl2.y - mCornerY);
        // 构造坐标矩阵
        float f8 = (mCornerX - mBezierControl1.x) / dis;
        float f9 = (mBezierControl2.y - mCornerY) / dis;
        mMatrixArray[0] = 1 - 2 * f9 * f9;
        mMatrixArray[1] = 2 * f8 * f9;
        mMatrixArray[3] = mMatrixArray[1];
        mMatrixArray[4] = 1 - 2 * f8 * f8;
        mMatrix.setValues(mMatrixArray);
        mMatrix.preTranslate(-mBezierControl1.x, -mBezierControl1.y);
        mMatrix.postTranslate(mBezierControl1.x, mBezierControl1.y);

        // 构造并绘制翻起页背面部分
        // 设置画笔颜色过滤器
        paint.setColorFilter(mColorMatrixFilter);
        // 绘制翻起页背面部分
        if (isPrevPage) {
            canvas.drawBitmap(mNewContentPageBitmap, mMatrix, paint);
        } else {
            canvas.drawBitmap(mOldContentPageBitmap, mMatrix, paint);
        }
        paint.setColorFilter(null);

        canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y);
        mFolderShadowDrawable.setBounds(left, (int) mBezierStart1.y, right,
                (int) (mBezierStart1.y + mMaxLength));
        mFolderShadowDrawable.draw(canvas);
        canvas.restore();
    }


    /** 终止翻页特效 */
    private void abortAnimation() {
        if (!mModeScroller.isFinished()) {
            mModeScroller.abortAnimation();
            mBezierControl1.set(0, 0);
            mBezierEnd1.set(0, 0);
            mBezierControl2.set(0, 0);
            mBezierEnd2.set(0, 0);
        }
    }

    // ***********************************************************仿真翻页处理


    // #########################################################自由拖动翻页处理

    /** 是否正在MODE_SCROLL模式下的scroll */
    private boolean isScrollingOnModeScroll;

    /**
     * 自由拖动动画
     * 
     * @param scrollMode -1,仿真翻页；0,拖动处理；1,点击向上处理；2,点击向下处理; isGoBsck是否是回翻(即翻页失败)
     */
    private void startScollAnimation(int scrollMode, boolean isGoBsck) {
        switch (pageTurnMode) {
            case PAGETURN_MODE_BOOK:
                int dx; // dx 水平方向滑动的距离，负值会使滚动向左滚动
                int dy; // dy 垂直方向滑动的距离，负值会使滚动向上滚动

                if (mScrollDirection == DIRECTION_LEFT && mTouch.y != mHeight - dI) {
                    PointF p = getCross(mBezierControl1, mBezierEnd1, mBezierControl2, mBezierEnd2);
                    if (p.x >= 0 && p.x <= mWidth && p.y >= 0 && p.y <= mHeight - dI
                            && mBezierControl1.x >= 0 && mBezierControl1.y >= 0
                            && mBezierControl2.x >= 0 && mBezierControl2.y >= 0
                            && mBezierEnd1.x >= 0 && mBezierEnd1.y >= 0 && mBezierEnd2.x >= 0
                            && mBezierEnd2.y >= 0 && Math.round(p.x) != Math.round(p.y)
                            && Math.round(mTouch.x) != Math.round(mTouch.y)) {
                        mTouch.set(p);
                    }
                }

                if (isGoBsck && mChangeScrollDirection != mScrollDirection) { // 如果是往回返执行该动画(即翻页失败)
                    if (mChangeScrollDirection == DIRECTION_LEFT) {
                        dx = (int) (-(mTouch.x + mWidth));
                        dy = (int) (mCornerY - mTouch.y);
                        mScrollDirection = DIRECTION_LEFT;
                    } else {
                        dx = (int) (2 * mWidth - mTouch.x);
                        dy = (int) (mCornerY - mTouch.y);
                        mScrollDirection = DIRECTION_RIGHT;
                    }
                } else {
                    if (mScrollDirection == DIRECTION_LEFT) {
                        dx = -(int) (mWidth + mTouch.x);
                    } else {
                        dx = (int) (mWidth - mTouch.x + mWidth);
                    }
                    if (mCornerY > 0) {
                        dy = (int) (mHeight - mTouch.y - dI);
                    } else {
                        dy = (int) (dI - mTouch.y); // 防止mTouch.y最终变为0
                    }
                }

                int amationTime = 0;
                if (dx < 0) {
                    amationTime = 400;
                } else {
                    amationTime = 600;
                }
                mModeScroller.startScroll((int) mTouch.x, (int) mTouch.y, dx, dy, amationTime); // 时间
                break;
            case PAGETURN_MODE_SCROLL:
                switch (scrollMode) {
                    case 0:
                        mModeScroller.fling(0, 0, 0, (int) mVelocityTracker.getYVelocity(),
                                Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE,
                                Integer.MAX_VALUE);
                        break;
                    case 1:// 向上翻
                        isScrollingOnModeScroll = true;
                        if (onViewEventListener != null) {
                            mLastTouchY = 0;
                            mModeScroller.startScroll(0, 0, 0,
                                    onViewEventListener.onViewDistanceInScrollMode(), 0);
                        }
                        break;
                    case 2:// 向下翻
                        isScrollingOnModeScroll = true;
                        if (onViewEventListener != null) {
                            mLastTouchY = 0;
                            mModeScroller.startScroll(0, 0, 0,
                                    -onViewEventListener.onViewDistanceInScrollMode(), 0);
                        }
                        break;
                }
                break;
            default:
                break;
        }
    }

    /**
     * 自由翻页绘制
     * 
     * @param canvas
     */
    private void drawScrollContentCanvas(Canvas canvas) {

        if (mNewContentPageBitmap == null) {
            return;
        }
        canvas.drawBitmap(mNewContentPageBitmap, 0, 0, null);
    }

    /** 调用startScroll方法就会调用这个方法， 来取得mTouch的动态坐标 */
    public void computeScroll() {
        if (pageTurnMode == PAGETURN_MODE_SMOOTH) {
            return;
        }
        if (mModeScroller.computeScrollOffset()) {
            System.out.println("touch="+mModeScroller.getCurrX()+":"+mModeScroller.getCurrY());
            mTouch.x = mModeScroller.getCurrX();
            mTouch.y = mModeScroller.getCurrY();
            if (mTouch.y >= mHeight - 1) {
                mTouch.y = mHeight - dI;
            } else if (mTouch.y < 1) {
                mTouch.y = 1;
            }

            if (pageTurnMode == PAGETURN_MODE_SCROLL) {
                if (onViewEventListener != null) {
                    onViewEventListener.onViewScroll(mModeScroller.getCurrY() - mLastTouchY);
                }
            }
            // mLastTouchY = 0;
            // mLastTouchX = 0;
            mLastTouchY = mModeScroller.getCurrY();
            // mLastTouchX = mModeScroller.getCurrX();
            postInvalidate();
        } else if (isScrollingOnModeScroll == true) {
            isScrollingOnModeScroll = false;
            if (onViewEventListener != null) {
                onViewEventListener.onViewScroll(mModeScroller.getFinalY() - mLastTouchY);
            }
            postInvalidate();
        }
    }

    // ######################################################################


    /** 设置View点击事件是否可用 */
    public void setClickEventEnabled(boolean isClickEnabled) {
        this.isClickEnabled = isClickEnabled;
    }

    /** 长按相关：当前touch时间的downtime */
    private long currentDownTime;
    private float longDownX;
    private float longDownY;

    private LinearLayout fuctionlLayout;
    private Button copyBtn;
    private Button shareBtn;

    /** 长按相关：长按时间检测线程 */
    private class LongClickThread extends Thread {
        private long nextcount = 0;

        public LongClickThread(long count) {
            this.nextcount = count;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(500);
                Log4an.i(TAG, "mScrollDirection:" + mScrollDirection);
                if (mScrollDirection == DIRECTION_VOID && nextcount == count) {
                    StatisticsUtils.onEvent(StatisticsEventID.LONGCLICK_COPY_AND_SHARE);
                    mScrollDirection = DIRECTION_LONGPRESS;
                    mIsTouched = false;
                    post(mLongPressRunnable);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 显示or更新复制功能控件(不都用PopupWindow是因为闪屏的问题无法解决)
     * 
     * @param isShowErrorBt 是否显示报错功能
     */
    public void showOrUpdateCopyController(PointF startPoint, PointF endPoint, boolean isShowErrorBt) {
        // 拖动按钮宽高
        int handleWidth = Math.round(24 * density) + 60; // Math.round(24 * density) + 40
        final int handleHeight = Math.round(24 * density) + 60; // Math.round(24 * density) + 40
        // 功能按钮宽高
        int fuctionWidth = Math.round(150 * density); // 150
        int fuctionHeight = Math.round(48 * density); // 40
        // 初始化控件
        if (copyController == null) {
            try {
                int w = Math.round(110 * density);
                int h = Math.round(75 * density);
                int x = Math.round(startPoint.x - w / 2);
                int y = Math.round(startPoint.y - h / 2 - h * 5 / 4);
                // TODO 放大镜res图片对应的大小 和位置
                // int w = Math.round(110 * density);
                // int h = Math.round(54 * density);
                // int x = Math.round(startPoint.x - w / 2);
                // int y = Math.round(startPoint.x - h / 2 - h * 5 / 4);
                if (x < 0) {
                    x = 0;
                } else if (x > getWidth() - w) {
                    x = getWidth() - w;
                }
                if (y > getHeight() - h) {
                    y = getHeight() - h;
                }
                AbsoluteLayout layout = new AbsoluteLayout(mActivity);
                // 拖动按钮
                ImageView leftButton = new ImageView(mActivity);
                ImageView rightButton = new ImageView(mActivity);
                leftButton.setId(1);
                rightButton.setId(2);
                leftButton.setScaleType(ScaleType.FIT_XY);
                rightButton.setScaleType(ScaleType.FIT_XY);
                leftButton.setPadding(20, 20, 20, 20);
                rightButton.setPadding(20, 20, 20, 20);
                leftButton.setImageResource(R.drawable.btn_copyhandle_left);
                rightButton.setImageResource(R.drawable.btn_copyhandle_right);
                layout.addView(
                        leftButton,
                        new AbsoluteLayout.LayoutParams(handleWidth, handleHeight, Math
                                .round(startPoint.x) - handleWidth / 2, Math.round(startPoint.y)
                                - handleHeight + 20));
                layout.addView(
                        rightButton,
                        new AbsoluteLayout.LayoutParams(handleWidth, handleHeight, Math
                                .round(startPoint.x) - handleWidth / 2,
                                Math.round(startPoint.y) - 20));
                leftButton.setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        switch (event.getAction()) {
                            case MotionEvent.ACTION_DOWN:
                                if (onViewEventListener != null) {
                                    // TODO
                                    copyPoint.set(event.getRawX(), event.getRawY() + mHeight
                                            - mScreenHeight);
                                    showOrUpdateMagnifier(copyPoint);
                                    mLastTouchX = event.getRawX();
                                    mLastTouchY = event.getRawY() + mHeight - mScreenHeight;
                                }
                                break;
                            case MotionEvent.ACTION_MOVE:
                                if (onViewEventListener != null
                                        && !(event.getRawX() == mLastTouchX && event.getRawY()
                                                + mHeight - mScreenHeight == mLastTouchY)) {
                                    onViewEventListener.onViewInLongClickTouching(event.getRawX(),
                                            // 最后一个 1 指的是 左手按钮
                                            event.getRawY() + mHeight - mScreenHeight, -1, -1, 1,
                                            longDownY, longDownX);
                                    copyPoint.set(event.getRawX(), event.getRawY() + mHeight
                                            - mScreenHeight);
                                    showOrUpdateMagnifier(copyPoint);
                                    mLastTouchX = event.getRawX();
                                    mLastTouchY = event.getRawY() + mHeight - mScreenHeight;
                                }
                                break;
                            default:
                                closeMagnifier();
                                break;
                        }
                        return true;
                    }
                });
                rightButton.setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        switch (event.getAction()) {
                            case MotionEvent.ACTION_DOWN:

                                if (onViewEventListener != null) {
                                    copyPoint.set(event.getRawX(), event.getRawY() + mHeight
                                            - mScreenHeight);
                                    showOrUpdateMagnifier(copyPoint);
                                    mLastTouchX = event.getRawX();
                                    mLastTouchY = event.getRawY() + mHeight - mScreenHeight;
                                }
                                break;
                            case MotionEvent.ACTION_MOVE:
                                if (onViewEventListener != null
                                        && !(event.getRawX() == mLastTouchX && event.getRawY()
                                                + mHeight - mScreenHeight == mLastTouchY)) {
                                    // 2 右
                                    onViewEventListener.onViewInLongClickTouching(-1, -1,
                                            event.getRawX(), event.getRawY() + mHeight
                                                    - mScreenHeight, 2, longDownY, longDownX);
                                    copyPoint.set(event.getRawX(), event.getRawY() + mHeight
                                            - mScreenHeight);
                                    showOrUpdateMagnifier(copyPoint);
                                    mLastTouchX = event.getRawX();
                                    mLastTouchY = event.getRawY() + mHeight - mScreenHeight;
                                }
                                break;
                            default:
                                closeMagnifier();
                                break;
                        }
                        return true;
                    }
                });
                // 放大镜
                LinearLayout subLayout = new LinearLayout(mActivity);
                ImageView iv = new ImageView(mActivity);
                iv.setScaleType(ScaleType.MATRIX);
                iv.setId(0);
                // subLayout.addView(iv, w, h);
                subLayout.addView(iv, w, h);
                subLayout.setVisibility(View.GONE);
                layout.addView(
                        subLayout,
                        new AbsoluteLayout.LayoutParams(w, h, x, y < 0 ? Math.round(startPoint.y
                                + h * 4 / 3) : y));

                fuctionlLayout = new LinearLayout(mActivity);
                fuctionlLayout.setId(3);
                copyBtn = new Button(mActivity);
                shareBtn = new Button(mActivity);
                copyBtn.setText("复制");
                shareBtn.setText("分享");
                copyBtn.setTextColor(Color.WHITE);
                shareBtn.setTextColor(Color.WHITE);
                copyBtn.setTextSize(16);
                shareBtn.setTextSize(16);
                copyBtn.setBackgroundResource(R.drawable.btn_copymode);
                shareBtn.setBackgroundResource(R.drawable.btn_copymode_right_up);

                View lineView1 = new View(mActivity);
                View lineView2 = new View(mActivity);
                lineView1.setBackgroundResource(R.drawable.line_bc_vertical);
                lineView2.setBackgroundResource(R.drawable.line_bc_vertical);
                fuctionlLayout.addView(copyBtn, new LinearLayout.LayoutParams(-1, -1, 1));
                fuctionlLayout.addView(lineView1, new LinearLayout.LayoutParams(2, -1));
                fuctionlLayout.addView(shareBtn, new LinearLayout.LayoutParams(-1, -1, 1));
                if (isShowErrorBt) {
                    Button errorBtn = new Button(mActivity);
                    errorBtn.setText("报错");
                    errorBtn.setTextColor(Color.WHITE);
                    errorBtn.setTextSize(16);
                    errorBtn.setBackgroundResource(R.drawable.btn_copymode);
                    fuctionlLayout.addView(lineView2, new LinearLayout.LayoutParams(2, -1));
                    fuctionlLayout.addView(errorBtn, new LinearLayout.LayoutParams(-1, -1, 1));
                    errorBtn.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (onViewEventListener != null) {
                                onViewEventListener.onViewCopyModeClicked(2);
                                onViewEventListener.onViewCopyModeCompleted();
                            }
                        }
                    });
                }
                fuctionlLayout.setBackgroundResource(R.drawable.bg_copymode_layout);
                fuctionlLayout.setVisibility(View.GONE);
                layout.addView(fuctionlLayout, new AbsoluteLayout.LayoutParams(fuctionWidth,
                        fuctionHeight, getWidth() / 2 - fuctionWidth / 2, 0));
                copyBtn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (onViewEventListener != null) {
                            onViewEventListener.onViewCopyModeClicked(0);
                            // onViewEventListener.onViewCopyModeCompleted();
                        }
                    }
                });
                shareBtn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (onViewEventListener != null) {
                            onViewEventListener.onViewCopyModeClicked(1);
                            onViewEventListener.onViewCopyModeCompleted();
                        }
                    }
                });

                copyController = new PopupWindow(layout, getWidth(), getHeight());
                copyController.setOutsideTouchable(false);
                copyController.setTouchable(true);
                copyController.setFocusable(false);
                copyController.setAnimationStyle(0);
                layout.setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        switch (event.getAction()) {
                            case MotionEvent.ACTION_DOWN:
                                downTouchX = event.getX();
                                downTouchY = event.getY();
                                break;
                            case MotionEvent.ACTION_MOVE:
                                if (Math.abs(downTouchX - event.getX()) > mTouchSlop
                                        || Math.abs(downTouchY - event.getY()) > mTouchSlop) {
                                    downTouchX = Float.MAX_VALUE;
                                    downTouchY = Float.MAX_VALUE;
                                }
                                break;
                            case MotionEvent.ACTION_UP:
                                if (Math.abs(downTouchX - event.getX()) <= mTouchSlop
                                        && Math.abs(downTouchY - event.getY()) <= mTouchSlop) {
                                    if (onViewEventListener != null) {
                                        onViewEventListener.onViewCopyModeCompleted();
                                    }
                                }
                                break;
                        }
                        return true;
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            // 显示复制控件
            if (!copyController.isShowing()) {
                copyController.showAsDropDown(this, 0, -getViewHeight());
                copyController.setWindowLayoutMode(ViewGroup.LayoutParams.FILL_PARENT,
                        ViewGroup.LayoutParams.FILL_PARENT);
            }
            // 显示拖动按钮
            View leftButton = copyController.getContentView().findViewById(1);
            View rightButton = copyController.getContentView().findViewById(2);
            AbsoluteLayout.LayoutParams lp1 =
                    ((AbsoluteLayout.LayoutParams) leftButton.getLayoutParams());
            lp1.x = Math.round(startPoint.x) - handleWidth / 2;
            lp1.y = Math.round(startPoint.y) - handleHeight + 20;
            leftButton.setLayoutParams(lp1);
            AbsoluteLayout.LayoutParams lp2 =
                    ((AbsoluteLayout.LayoutParams) rightButton.getLayoutParams());
            lp2.x = Math.round(endPoint.x) - handleWidth / 2;
            lp2.y = Math.round(endPoint.y) - 20;
            rightButton.setLayoutParams(lp2);
            // 更新控制按钮位置
            View fuctionLayout = copyController.getContentView().findViewById(3);
            AbsoluteLayout.LayoutParams lp3 =
                    ((AbsoluteLayout.LayoutParams) fuctionLayout.getLayoutParams());
            lp3.x = getWidth() / 2 - fuctionWidth / 2;
            lp3.y = Math.round(startPoint.y - fuctionHeight * 2);// 5/3
            if (lp3.y < 0) {
                // fuctionlLayout.setBackgroundResource(R.drawable.bg_copymode_layout_up);
                lp3.y = Math.round(endPoint.y + fuctionHeight * 6 / 5);
            }
            if (lp3.y + fuctionHeight > mHeight) {
                // fuctionlLayout.setBackgroundResource(R.drawable.bg_copymode_layout);
                lp3.y = mHeight / 2 - fuctionHeight * 2 / 5;
            }

            if (lp3.y > lp2.y) {
                fuctionlLayout.setBackgroundResource(R.drawable.bg_copymode_layout_up);
            } else {
                fuctionlLayout.setBackgroundResource(R.drawable.bg_copymode_layout);
            }
            fuctionLayout.setLayoutParams(lp3);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /** 获取自定义View的高度 */
    private int getViewHeight() {
        if (mHeight == 0) {
            DisplayMetrics dm = new DisplayMetrics();
            mActivity.getWindowManager().getDefaultDisplay().getMetrics(dm);
            return dm.heightPixels;
        }
        return this.mHeight;
    }

    /** 打开放大镜 */
    public void showOrUpdateMagnifier(PointF point) {
        // Log4an.i(TAG, "--------打开放大镜---------");
        try {
            if (copyController == null)
                return;
            int w = Math.round(125 * density);
            int h = Math.round(75 * density);
            int x = Math.round(point.x - w / 2);
            int y = Math.round(point.y - h / 2 - h * 5 / 4);
            // TODO 放大效果区域 对应的大小 和位置
            // int w = Math.round(110 * density);
            // int h = Math.round(54 * density);
            // int x = Math.round(point.x - w / 2);
            // int y = Math.round(point.x - h / 2 - h * 5 / 4);

            if (x < 0) {
                x = 0;
            } else if (x > getWidth() - w) {
                x = getWidth() - w;
            }
            if (y > getHeight() - h) {
                y = getHeight() - h;
            }
            ImageView iv = (ImageView) copyController.getContentView().findViewById(0);
            LinearLayout subLayout = (LinearLayout) iv.getParent();
            if (y < 0) {
                subLayout.setBackgroundResource(R.drawable.bg_magnifier_plus);
            } else {
                subLayout.setBackgroundResource(R.drawable.bg_magnifier);
            }
            LayoutParams params = iv.getLayoutParams();
            params.width = w - subLayout.getPaddingLeft() - subLayout.getPaddingRight();
            params.height = h - subLayout.getPaddingTop() - subLayout.getPaddingBottom();
            iv.setLayoutParams(params);
            Bitmap bitmap = getDrawingCache();

            this.onDraw(new Canvas(bitmap));
            invalidate();
            if (bitmap != null && !bitmap.isRecycled()) {
                Matrix m = iv.getImageMatrix();
                if (m == null) {
                    m = new Matrix();
                }
                int subX = Math.round(point.x * 1.5f - iv.getWidth() / 2);
                int subY =
                        Math.round(point.y * 1.5f
                                - (h - subLayout.getPaddingTop() - subLayout.getPaddingBottom())
                                / 2);
                if (subX < 0) {
                    subX = 0;
                } else if (subX > getWidth() * 1.5f - iv.getWidth()) {
                    subX = (int) (getWidth() * 1.5f - iv.getWidth());
                }
                if (subY < 0) {
                    subY = 0;
                } else if (subY > getHeight() * 1.5f
                        - (h - subLayout.getPaddingTop() - subLayout.getPaddingBottom())) {
                    subY =
                            (int) (getHeight() * 1.5f - (h - subLayout.getPaddingTop() - subLayout
                                    .getPaddingBottom()));
                }
                m.setScale(1.5f, 1.5f, 0, 0);
                // m.setRotate(w,-subX, -subY);
                m.postTranslate(-subX, -subY);

                iv.setImageMatrix(m);
                iv.setImageBitmap(bitmap);
                AbsoluteLayout.LayoutParams lp =
                        ((AbsoluteLayout.LayoutParams) subLayout.getLayoutParams());
                lp.x = x;
                lp.y = y < 0 ? Math.round(point.y + h * 4 / 3) : y;
                subLayout.setLayoutParams(lp);
            }
            View fuctionLayout = copyController.getContentView().findViewById(3);
            fuctionLayout.setVisibility(View.GONE);
            subLayout.setVisibility(View.VISIBLE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /** 关闭放大镜 */
    public void closeMagnifier() {
        try {
            if (copyController != null) {
                ImageView iv = (ImageView) copyController.getContentView().findViewById(0);
                LinearLayout subLayout = (LinearLayout) iv.getParent();
                subLayout.setVisibility(View.GONE);
                View fuctionLayout = copyController.getContentView().findViewById(3);
                fuctionLayout.setVisibility(View.VISIBLE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /** 隐藏复制控件 */
    public void dismissCopyController() {
        try {
            if (copyController != null && copyController.isShowing()) {
                copyController.dismiss();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * <b>获得当前翻页特效</b><br>
     * 仿真翻页：MODE_BOOK<br>
     * 拖动翻页：MODE_SCROLL
     */
    public int getPageTurnMode() {
        return pageTurnMode;
    }

    /** 获得默认画面的Picture */
    public Picture getDefaultPagePicture() {
        return defaultPagePicture;
    }

    public void setDefaultPagePicture(Picture p) {
        defaultPagePicture = p;
    }

}
